home *** CD-ROM | disk | FTP | other *** search
/ Team Palmtops 7 / Palmtops_numero07.iso / WinCE / SDKWindowsCE / HandHeldPCPro30 / sdk.exe / Jupiter SDK / data1.cab / MFC / src / cmdtarg.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1999-02-19  |  21.4 KB  |  871 lines

  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1992-1998 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Microsoft Foundation Classes Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Microsoft Foundation Classes product.
  10.  
  11. #include "stdafx.h"
  12. #include "occimpl.h"
  13.  
  14. #ifdef AFX_CORE1_SEG
  15. #pragma code_seg(AFX_CORE1_SEG)
  16. #endif
  17.  
  18. #ifdef _DEBUG
  19. #undef THIS_FILE
  20. static char THIS_FILE[] = __FILE__;
  21. #endif
  22.  
  23. #define new DEBUG_NEW
  24.  
  25. /////////////////////////////////////////////////////////////////////////////
  26. // CCmdTarget construction/destruction
  27.  
  28. CCmdTarget::CCmdTarget()
  29. {
  30.     // capture module state where object was constructed
  31. #ifdef _AFXDLL
  32.     m_pModuleState = AfxGetModuleState();
  33.     ASSERT(m_pModuleState != NULL);
  34. #endif
  35.  
  36.     // initialize state
  37. #ifndef _AFX_NO_OLE_SUPPORT
  38.     m_dwRef = 1;
  39.     m_pOuterUnknown = NULL;
  40.     m_xInnerUnknown = 0;
  41.     m_xDispatch.m_vtbl = 0;
  42.     m_bResultExpected = TRUE;
  43.     m_xConnPtContainer.m_vtbl = 0;
  44. #endif
  45. }
  46.  
  47. CCmdTarget::~CCmdTarget()
  48. {
  49. #ifndef _AFX_NO_OLE_SUPPORT
  50.     if (m_xDispatch.m_vtbl != 0)
  51.         ((COleDispatchImpl*)&m_xDispatch)->Disconnect();
  52.     ASSERT(m_dwRef <= 1);
  53. #endif
  54. #ifdef _AFXDLL
  55.     m_pModuleState = NULL;
  56. #endif
  57. }
  58.  
  59. /////////////////////////////////////////////////////////////////////////////
  60. // CCmdTarget windows message dispatching
  61.  
  62. AFX_STATIC BOOL AFXAPI _AfxDispatchCmdMsg(CCmdTarget* pTarget, UINT nID, int nCode,
  63.     AFX_PMSG pfn, void* pExtra, UINT nSig, AFX_CMDHANDLERINFO* pHandlerInfo)
  64.         // return TRUE to stop routing
  65. {
  66.     ASSERT_VALID(pTarget);
  67.     UNUSED(nCode);   // unused in release builds
  68.  
  69.     union MessageMapFunctions mmf;
  70.     mmf.pfn = pfn;
  71.     BOOL bResult = TRUE; // default is ok
  72.  
  73.     if (pHandlerInfo != NULL)
  74.     {
  75.         // just fill in the information, don't do it
  76.         pHandlerInfo->pTarget = pTarget;
  77.         pHandlerInfo->pmf = mmf.pfn;
  78.         return TRUE;
  79.     }
  80.  
  81.     switch (nSig)
  82.     {
  83.     case AfxSig_vv:
  84.         // normal command or control notification
  85.         ASSERT(CN_COMMAND == 0);        // CN_COMMAND same as BN_CLICKED
  86.         ASSERT(pExtra == NULL);
  87.         (pTarget->*mmf.pfn_COMMAND)();
  88.         break;
  89.  
  90.     case AfxSig_bv:
  91.         // normal command or control notification
  92.         ASSERT(CN_COMMAND == 0);        // CN_COMMAND same as BN_CLICKED
  93.         ASSERT(pExtra == NULL);
  94.         bResult = (pTarget->*mmf.pfn_bCOMMAND)();
  95.         break;
  96.  
  97.     case AfxSig_vw:
  98.         // normal command or control notification in a range
  99.         ASSERT(CN_COMMAND == 0);        // CN_COMMAND same as BN_CLICKED
  100.         ASSERT(pExtra == NULL);
  101.         (pTarget->*mmf.pfn_COMMAND_RANGE)(nID);
  102.         break;
  103.  
  104.     case AfxSig_bw:
  105.         // extended command (passed ID, returns bContinue)
  106.         ASSERT(pExtra == NULL);
  107.         bResult = (pTarget->*mmf.pfn_COMMAND_EX)(nID);
  108.         break;
  109.  
  110.     case AfxSig_vNMHDRpl:
  111.         {
  112.             AFX_NOTIFY* pNotify = (AFX_NOTIFY*)pExtra;
  113.             ASSERT(pNotify != NULL);
  114.             ASSERT(pNotify->pResult != NULL);
  115.             ASSERT(pNotify->pNMHDR != NULL);
  116.             (pTarget->*mmf.pfn_NOTIFY)(pNotify->pNMHDR, pNotify->pResult);
  117.         }
  118.         break;
  119.     case AfxSig_bNMHDRpl:
  120.         {
  121.             AFX_NOTIFY* pNotify = (AFX_NOTIFY*)pExtra;
  122.             ASSERT(pNotify != NULL);
  123.             ASSERT(pNotify->pResult != NULL);
  124.             ASSERT(pNotify->pNMHDR != NULL);
  125.             bResult = (pTarget->*mmf.pfn_bNOTIFY)(pNotify->pNMHDR, pNotify->pResult);
  126.         }
  127.         break;
  128.     case AfxSig_vwNMHDRpl:
  129.         {
  130.             AFX_NOTIFY* pNotify = (AFX_NOTIFY*)pExtra;
  131.             ASSERT(pNotify != NULL);
  132.             ASSERT(pNotify->pResult != NULL);
  133.             ASSERT(pNotify->pNMHDR != NULL);
  134.             (pTarget->*mmf.pfn_NOTIFY_RANGE)(nID, pNotify->pNMHDR,
  135.                 pNotify->pResult);
  136.         }
  137.         break;
  138.     case AfxSig_bwNMHDRpl:
  139.         {
  140.             AFX_NOTIFY* pNotify = (AFX_NOTIFY*)pExtra;
  141.             ASSERT(pNotify != NULL);
  142.             ASSERT(pNotify->pResult != NULL);
  143.             ASSERT(pNotify->pNMHDR != NULL);
  144.             bResult = (pTarget->*mmf.pfn_NOTIFY_EX)(nID, pNotify->pNMHDR,
  145.                 pNotify->pResult);
  146.         }
  147.         break;
  148.     case AfxSig_cmdui:
  149.         {
  150.             // ON_UPDATE_COMMAND_UI or ON_UPDATE_COMMAND_UI_REFLECT case
  151.             ASSERT(CN_UPDATE_COMMAND_UI == (UINT)-1);
  152.             ASSERT(nCode == CN_UPDATE_COMMAND_UI || nCode == 0xFFFF);
  153.             ASSERT(pExtra != NULL);
  154.             CCmdUI* pCmdUI = (CCmdUI*)pExtra;
  155.             ASSERT(!pCmdUI->m_bContinueRouting);    // idle - not set
  156.             (pTarget->*mmf.pfn_UPDATE_COMMAND_UI)(pCmdUI);
  157.             bResult = !pCmdUI->m_bContinueRouting;
  158.             pCmdUI->m_bContinueRouting = FALSE;     // go back to idle
  159.         }
  160.         break;
  161.  
  162.     case AfxSig_cmduiw:
  163.         {
  164.             // ON_UPDATE_COMMAND_UI case
  165.             ASSERT(nCode == CN_UPDATE_COMMAND_UI);
  166.             ASSERT(pExtra != NULL);
  167.             CCmdUI* pCmdUI = (CCmdUI*)pExtra;
  168.             ASSERT(pCmdUI->m_nID == nID);           // sanity assert
  169.             ASSERT(!pCmdUI->m_bContinueRouting);    // idle - not set
  170.             (pTarget->*mmf.pfn_UPDATE_COMMAND_UI_RANGE)(pCmdUI, nID);
  171.             bResult = !pCmdUI->m_bContinueRouting;
  172.             pCmdUI->m_bContinueRouting = FALSE;     // go back to idle
  173.         }
  174.         break;
  175.  
  176.     // general extensibility hooks
  177.     case AfxSig_vpv:
  178.         (pTarget->*mmf.pfn_OTHER)(pExtra);
  179.         break;
  180.     case AfxSig_bpv:
  181.         bResult = (pTarget->*mmf.pfn_OTHER_EX)(pExtra);
  182.         break;
  183.  
  184.     default:    // illegal
  185.         ASSERT(FALSE);
  186.         return 0;
  187.     }
  188.     return bResult;
  189. }
  190.  
  191. // compare two pointers to GUIDs -- TRUE if both pointers are NULL
  192. // or both pointers point to same GUID; FALSE otherwise
  193.  
  194. #define IsEqualNULLGuid(pGuid1, pGuid2) \
  195.     (((pGuid1) == NULL && (pGuid2) == NULL) || \
  196.      ((pGuid1) != NULL && (pGuid2) != NULL && \
  197.         IsEqualGUID(*(pGuid1), *(pGuid2))))
  198.  
  199.  
  200. BOOL CCmdTarget::OnCmdMsg(UINT nID, int nCode, void* pExtra,
  201.     AFX_CMDHANDLERINFO* pHandlerInfo)
  202. {
  203. #ifndef _AFX_NO_OCC_SUPPORT
  204.     // OLE control events are a special case
  205.     if (nCode == CN_EVENT)
  206.     {
  207.         ASSERT(afxOccManager != NULL);
  208.         return afxOccManager->OnEvent(this, nID, (AFX_EVENT*)pExtra, pHandlerInfo);
  209.     }
  210. #endif // !_AFX_NO_OCC_SUPPORT
  211.  
  212.     // determine the message number and code (packed into nCode)
  213.     const AFX_MSGMAP* pMessageMap;
  214.     const AFX_MSGMAP_ENTRY* lpEntry;
  215.     UINT nMsg = 0;
  216.  
  217. #ifndef _AFX_NO_DOCOBJECT_SUPPORT
  218.     if (nCode == CN_OLECOMMAND)
  219.     {
  220.         BOOL bResult = FALSE;
  221.  
  222.         const AFX_OLECMDMAP* pOleCommandMap;
  223.         const AFX_OLECMDMAP_ENTRY* pEntry;
  224.  
  225.         COleCmdUI* pUI = (COleCmdUI*) pExtra;
  226.         const GUID* pguidCmdGroup = pUI->m_pguidCmdGroup;
  227.  
  228. #ifdef _AFXDLL
  229.         for (pOleCommandMap = GetCommandMap(); pOleCommandMap != NULL && !bResult;
  230.             pOleCommandMap = pOleCommandMap->pfnGetBaseMap())
  231. #else
  232.         for (pOleCommandMap = GetCommandMap(); pOleCommandMap != NULL && !bResult;
  233.             pOleCommandMap = pOleCommandMap->pBaseMap)
  234. #endif
  235.         {
  236.             for (pEntry = pOleCommandMap->lpEntries;
  237.                 pEntry->cmdID != 0 && pEntry->nID != 0 && !bResult;
  238.                 pEntry++)
  239.             {
  240.                 if (nID == pEntry->cmdID &&
  241.                     IsEqualNULLGuid(pguidCmdGroup, pEntry->pguid))
  242.                 {
  243.                     pUI->m_nID = pEntry->nID;
  244.                     bResult = TRUE;
  245.                 }
  246.             }
  247.         }
  248.  
  249.         return bResult;
  250.     }
  251. #endif
  252.  
  253.     if (nCode != CN_UPDATE_COMMAND_UI)
  254.     {
  255.         nMsg = HIWORD(nCode);
  256.         nCode = LOWORD(nCode);
  257.     }
  258.  
  259.     // for backward compatibility HIWORD(nCode)==0 is WM_COMMAND
  260.     if (nMsg == 0)
  261.         nMsg = WM_COMMAND;
  262.  
  263.     // look through message map to see if it applies to us
  264. #ifdef _AFXDLL
  265.     for (pMessageMap = GetMessageMap(); pMessageMap != NULL;
  266.       pMessageMap = (*pMessageMap->pfnGetBaseMap)())
  267. #else
  268.     for (pMessageMap = GetMessageMap(); pMessageMap != NULL;
  269.       pMessageMap = pMessageMap->pBaseMap)
  270. #endif
  271.     {
  272.         // Note: catches BEGIN_MESSAGE_MAP(CMyClass, CMyClass)!
  273. #ifdef _AFXDLL
  274.         ASSERT(pMessageMap != (*pMessageMap->pfnGetBaseMap)());
  275. #else
  276.         ASSERT(pMessageMap != pMessageMap->pBaseMap);
  277. #endif
  278.  
  279.         lpEntry = AfxFindMessageEntry(pMessageMap->lpEntries, nMsg, nCode, nID);
  280.         if (lpEntry != NULL)
  281.         {
  282.             // found it
  283. #ifdef _DEBUG
  284.             if (afxTraceFlags & traceCmdRouting)
  285.             {
  286.                 if (nCode == CN_COMMAND)
  287.                 {
  288.                     TRACE2("SENDING command id 0x%04X to %hs target.\n", nID,
  289.                         GetRuntimeClass()->m_lpszClassName);
  290.                 }
  291.                 else if (nCode > CN_COMMAND)
  292.                 {
  293.                     if (afxTraceFlags & traceWinMsg)
  294.                     {
  295.                         TRACE3("SENDING control notification %d from control id 0x%04X to %hs window.\n",
  296.                             nCode, nID, GetRuntimeClass()->m_lpszClassName);
  297.                     }
  298.                 }
  299.             }
  300. #endif //_DEBUG
  301.             return _AfxDispatchCmdMsg(this, nID, nCode,
  302.                 lpEntry->pfn, pExtra, lpEntry->nSig, pHandlerInfo);
  303.         }
  304.     }
  305.     return FALSE;   // not handled
  306. }
  307.  
  308. /////////////////////////////////////////////////////////////////////////////
  309. // Hook to disable automation handlers
  310.  
  311. #ifndef _AFX_NO_OLE_SUPPORT
  312.  
  313. BOOL CCmdTarget::IsInvokeAllowed(DISPID)
  314. {
  315.     return TRUE;    // normally, invoke is always allowed
  316. }
  317.  
  318. #endif // !_AFX_NO_OLE_SUPPORT
  319.  
  320. /////////////////////////////////////////////////////////////////////////////
  321. // Stubs for OLE type library functions
  322.  
  323. #ifndef _AFX_NO_OLE_SUPPORT
  324.  
  325. BOOL CCmdTarget::GetDispatchIID(IID*)
  326. {
  327.     // Subclass must implement (typically via COleControl implementation)
  328.     return FALSE;
  329. }
  330.  
  331. UINT CCmdTarget::GetTypeInfoCount()
  332. {
  333.     // Subclass must implement (typically via IMPLEMENT_OLETYPELIB macro)
  334.     return 0;
  335. }
  336.  
  337. CTypeLibCache* CCmdTarget::GetTypeLibCache()
  338. {
  339.     // Subclass must implement (typically via IMPLEMENT_OLETYPELIB macro)
  340.     return NULL;
  341. }
  342.  
  343. HRESULT CCmdTarget::GetTypeLib(LCID, LPTYPELIB*)
  344. {
  345.     // Subclass must implement (typically via IMPLEMENT_OLETYPELIB macro)
  346.     return TYPE_E_CANTLOADLIBRARY;
  347. }
  348.  
  349. #endif // !_AFX_NO_OLE_SUPPORT
  350.  
  351. /////////////////////////////////////////////////////////////////////////////
  352. // CCmdTarget routines that delegate to the WinApp
  353.  
  354. void CCmdTarget::BeginWaitCursor()
  355.     { AfxGetApp()->DoWaitCursor(1); }
  356. void CCmdTarget::EndWaitCursor()
  357.     { AfxGetApp()->DoWaitCursor(-1); }
  358. void CCmdTarget::RestoreWaitCursor()
  359.     { AfxGetApp()->DoWaitCursor(0); }
  360.  
  361. /////////////////////////////////////////////////////////////////////////////
  362. // Root of message maps
  363.  
  364. const AFX_DATADEF AFX_MSGMAP CCmdTarget::messageMap =
  365. {
  366. #ifdef _AFXDLL
  367.     &CCmdTarget::_GetBaseMessageMap,
  368. #else
  369.     NULL,
  370. #endif
  371.     &CCmdTarget::_messageEntries[0]
  372. };
  373.  
  374. #ifdef _AFXDLL
  375. const AFX_MSGMAP* CCmdTarget::_GetBaseMessageMap()
  376. {
  377.     return NULL;
  378. }
  379. #endif
  380.  
  381. const AFX_MSGMAP* CCmdTarget::GetMessageMap() const
  382. {
  383.     return &CCmdTarget::messageMap;
  384. }
  385.  
  386. const AFX_MSGMAP_ENTRY CCmdTarget::_messageEntries[] =
  387. {
  388.     { 0, 0, AfxSig_end, 0 }     // nothing here
  389. };
  390.  
  391. /////////////////////////////////////////////////////////////////////////////
  392. // Root of dispatch maps
  393.  
  394. #ifndef _AFX_NO_OLE_SUPPORT
  395.  
  396. UINT CCmdTarget::_dispatchEntryCount = (UINT)-1;
  397. DWORD CCmdTarget::_dwStockPropMask = (DWORD)-1;
  398.  
  399. const AFX_DISPMAP CCmdTarget::dispatchMap =
  400. {
  401. #ifdef _AFXDLL
  402.     &CCmdTarget::_GetBaseDispatchMap,
  403. #else
  404.     NULL,
  405. #endif
  406.     &CCmdTarget::_dispatchEntries[0],
  407.     &CCmdTarget::_dispatchEntryCount,
  408.     &CCmdTarget::_dwStockPropMask
  409. };
  410.  
  411. #ifdef _AFXDLL
  412. const AFX_DISPMAP* CCmdTarget::_GetBaseDispatchMap()
  413. {
  414.     return NULL;
  415. }
  416. #endif
  417.  
  418. const AFX_DISPMAP* CCmdTarget::GetDispatchMap() const
  419. {
  420.     return &CCmdTarget::dispatchMap;
  421. }
  422.  
  423. const AFX_DISPMAP_ENTRY CCmdTarget::_dispatchEntries[] =
  424. {
  425.     { NULL, -1, NULL, 0, (AFX_PMSG)NULL, (AFX_PMSG)NULL, (size_t)-1,
  426.       afxDispCustom }
  427.     // nothing here
  428. };
  429.  
  430. #endif //!_AFX_NO_OLE_SUPPORT
  431.  
  432. /////////////////////////////////////////////////////////////////////////////
  433. // Root of event sink maps
  434.  
  435. #ifndef _AFX_NO_OCC_SUPPORT
  436.  
  437. UINT CCmdTarget::_eventsinkEntryCount = (UINT)-1;
  438.  
  439. const AFX_EVENTSINKMAP CCmdTarget::eventsinkMap =
  440. {
  441. #ifdef _AFXDLL
  442.     &CCmdTarget::_GetBaseEventSinkMap,
  443. #else
  444.     NULL,
  445. #endif
  446.     &CCmdTarget::_eventsinkEntries[0],
  447.     &CCmdTarget::_eventsinkEntryCount
  448. };
  449.  
  450. #ifdef _AFXDLL
  451. const AFX_EVENTSINKMAP* CCmdTarget::_GetBaseEventSinkMap()
  452. {
  453.     return NULL;
  454. }
  455. #endif
  456.  
  457. const AFX_EVENTSINKMAP* CCmdTarget::GetEventSinkMap() const
  458. {
  459.     return &CCmdTarget::eventsinkMap;
  460. }
  461.  
  462. const AFX_EVENTSINKMAP_ENTRY CCmdTarget::_eventsinkEntries[] =
  463. {
  464.     { NULL, -1, NULL, 0, (AFX_PMSG)NULL, (AFX_PMSG)NULL, (size_t)-1,
  465.       afxDispCustom, (UINT)-1, (UINT)-1 }
  466.     // nothing here
  467. };
  468.  
  469. #endif //!_AFX_NO_OCC_SUPPORT
  470.  
  471. /////////////////////////////////////////////////////////////////////////////
  472. // Root of interface maps
  473.  
  474. #ifndef _AFX_NO_OLE_SUPPORT
  475.  
  476. #ifdef _AFXDLL
  477. const AFX_INTERFACEMAP* CCmdTarget::_GetBaseInterfaceMap()
  478. {
  479.     return NULL;
  480. }
  481. #endif
  482.  
  483. const AFX_INTERFACEMAP* CCmdTarget::GetInterfaceMap() const
  484. {
  485.     return &CCmdTarget::interfaceMap;
  486. }
  487.  
  488. const AFX_INTERFACEMAP CCmdTarget::interfaceMap =
  489. {
  490. #ifdef _AFXDLL
  491.     &CCmdTarget::_GetBaseInterfaceMap,
  492. #else
  493.     NULL,
  494. #endif
  495.     &CCmdTarget::_interfaceEntries[0]
  496. };
  497.  
  498. #if defined(_WIN32_WCE)
  499. // private definitions of IIDs to avoid linking with uuid.lib
  500. static const IID IID_IDispatch =
  501.     { 0x00020400, 0, 0, { 0xC0, 0, 0, 0, 0, 0, 0, 0x46 } };
  502. #endif // _WIN32_WCE
  503. const AFX_INTERFACEMAP_ENTRY CCmdTarget::_interfaceEntries[] =
  504. {
  505. #ifndef _AFX_NO_OLE_SUPPORT
  506.     INTERFACE_PART(CCmdTarget, IID_IDispatch, Dispatch)
  507. #endif
  508.     { NULL, (size_t)-1 }    // end of entries
  509. };
  510.  
  511. void CCmdTarget::OnFinalRelease()
  512. {
  513. #ifndef _AFX_NO_OLE_SUPPORT
  514.     AfxLockGlobals(CRIT_TYPELIBCACHE);
  515.  
  516.     // release the typelib cache, if any
  517.     CTypeLibCache* pTypeLibCache = GetTypeLibCache();
  518.     if (pTypeLibCache != NULL)
  519.         pTypeLibCache->Unlock();
  520.  
  521.     AfxUnlockGlobals(CRIT_TYPELIBCACHE);
  522. #endif
  523.  
  524.     delete this;
  525. }
  526.  
  527. BOOL CCmdTarget::OnCreateAggregates()
  528. {
  529.     return TRUE;
  530. }
  531.  
  532. LPUNKNOWN CCmdTarget::GetInterfaceHook(const void*)
  533. {
  534.     return NULL;
  535. }
  536.  
  537. #endif //!_AFX_NO_OLE_SUPPORT
  538.  
  539. /////////////////////////////////////////////////////////////////////////////
  540. // Root of connection maps
  541.  
  542. #ifndef _AFX_NO_OLE_SUPPORT
  543.  
  544. #ifdef _AFXDLL
  545. const AFX_CONNECTIONMAP* CCmdTarget::_GetBaseConnectionMap()
  546. {
  547.     return NULL;
  548. }
  549. #endif
  550.  
  551. const AFX_CONNECTIONMAP* CCmdTarget::GetConnectionMap() const
  552. {
  553.     return &CCmdTarget::connectionMap;
  554. }
  555.  
  556. const AFX_CONNECTIONMAP CCmdTarget::connectionMap =
  557. {
  558. #ifdef _AFXDLL
  559.     &CCmdTarget::_GetBaseConnectionMap,
  560. #else
  561.     NULL,
  562. #endif
  563.     &CCmdTarget::_connectionEntries[0]
  564. };
  565.  
  566. const AFX_CONNECTIONMAP_ENTRY CCmdTarget::_connectionEntries[] =
  567. {
  568.     { NULL, (size_t)-1 }    // end of entries
  569. };
  570.  
  571. LPCONNECTIONPOINT CCmdTarget::GetConnectionHook(const IID&)
  572. {
  573.     return NULL;
  574. }
  575.  
  576. BOOL CCmdTarget::GetExtraConnectionPoints(CPtrArray*)
  577. {
  578.     return FALSE;
  579. }
  580.  
  581. #endif //!_AFX_NO_OLE_SUPPORT
  582.  
  583. /////////////////////////////////////////////////////////////////////////////
  584. // Root of command target maps
  585.  
  586. #ifndef _AFX_NO_DOCOBJECT_SUPPORT
  587.  
  588. #ifdef _AFXDLL
  589. const AFX_OLECMDMAP* CCmdTarget::_GetBaseCommandMap()
  590. {
  591.     return NULL;
  592. }
  593. #endif
  594.  
  595. const AFX_OLECMDMAP CCmdTarget::commandMap =
  596. {
  597. #ifdef _AFXDLL
  598.     &CCmdTarget::_GetBaseCommandMap,
  599. #else
  600.     NULL,
  601. #endif
  602.     &CCmdTarget::_commandEntries[0]
  603. };
  604.  
  605. const AFX_OLECMDMAP_ENTRY CCmdTarget::_commandEntries[] =
  606. {
  607.     { NULL, 0, 0 }    // end of entries
  608. };
  609.  
  610. const AFX_OLECMDMAP* CCmdTarget::GetCommandMap() const
  611. {
  612.     return &CCmdTarget::commandMap;
  613. }
  614.  
  615. #endif //!_AFX_NO_DOCOBJECT_SUPPORT
  616.  
  617. /////////////////////////////////////////////////////////////////////////////
  618. // Special access to view routing info
  619.  
  620. CView* CCmdTarget::GetRoutingView()
  621. {
  622.     return GetRoutingView_();
  623. }
  624.  
  625. CFrameWnd* CCmdTarget::GetRoutingFrame()
  626. {
  627.     return GetRoutingFrame_();
  628. }
  629.  
  630. /////////////////////////////////////////////////////////////////////////////
  631. // CCmdUI - User Interface for a command
  632.  
  633. // CCmdUI is a protocol class for all command handler variants
  634. //      CCmdUI is an implementation class for menus and general dialog
  635. //        controls (usually buttons)
  636.  
  637. CCmdUI::CCmdUI()
  638. {
  639.     // zero out everything
  640.     m_nID = m_nIndex = m_nIndexMax = 0;
  641.     m_pMenu = m_pSubMenu = m_pParentMenu = NULL;
  642.     m_pOther = NULL;
  643.     m_bEnableChanged = m_bContinueRouting = FALSE;
  644. }
  645.  
  646. // default CCmdUI implementation only works for Menu Items
  647. void CCmdUI::Enable(BOOL bOn)
  648. {
  649.     if (m_pMenu != NULL)
  650.     {
  651.         if (m_pSubMenu != NULL)
  652.             return; // don't change popup menus indirectly
  653.  
  654.         ASSERT(m_nIndex < m_nIndexMax);
  655.         m_pMenu->EnableMenuItem(m_nIndex, MF_BYPOSITION |
  656.             (bOn ? MF_ENABLED : (MF_DISABLED | MF_GRAYED)));
  657.     }
  658.     else
  659.     {
  660.         // enable/disable a control (i.e. child window)
  661.         ASSERT(m_pOther != NULL);
  662.  
  663.         // if control has the focus, move the focus before disabling
  664.         if (!bOn && (::GetFocus() == m_pOther->m_hWnd))
  665.             m_pOther->GetParent()->GetNextDlgTabItem(m_pOther)->SetFocus();
  666.         m_pOther->EnableWindow(bOn);
  667.     }
  668.     m_bEnableChanged = TRUE;
  669. }
  670.  
  671. void CCmdUI::SetCheck(int nCheck)
  672. {
  673.     if (m_pMenu != NULL)
  674.     {
  675.         if (m_pSubMenu != NULL)
  676.             return; // don't change popup menus indirectly
  677.  
  678.         // place checkmark next to menu item
  679.         ASSERT(m_nIndex < m_nIndexMax);
  680.         m_pMenu->CheckMenuItem(m_nIndex, MF_BYPOSITION |
  681.             (nCheck ? MF_CHECKED : MF_UNCHECKED));
  682.     }
  683.     else
  684.     {
  685.         // we can only check buttons or controls acting like buttons
  686.         ASSERT(m_pOther != NULL);
  687.         if (m_pOther->SendMessage(WM_GETDLGCODE) & DLGC_BUTTON)
  688.             m_pOther->SendMessage(BM_SETCHECK, nCheck);
  689.         // otherwise ignore it
  690.     }
  691. }
  692.  
  693. AFX_STATIC void AFXAPI _AfxLoadDotBitmap(); // for swap tuning
  694.  
  695. void CCmdUI::SetRadio(BOOL bOn)
  696. {
  697.     SetCheck(bOn ? 1 : 0); // this default works for most things as well
  698. #if !defined(_WIN32_WCE)
  699.     if (m_pMenu != NULL)
  700.     {
  701.         if (m_pSubMenu != NULL)
  702.             return; // don't change popup menus indirectly
  703.  
  704.         // for menu item - use dot instead of checkmark
  705.         ASSERT(m_nIndex < m_nIndexMax);
  706.  
  707.         if (afxData.hbmMenuDot == NULL)
  708.             _AfxLoadDotBitmap();    // in INIT segment
  709.  
  710.         if (afxData.hbmMenuDot != NULL)
  711.             SetMenuItemBitmaps(m_pMenu->m_hMenu, m_nIndex, MF_BYPOSITION,
  712.                 NULL, afxData.hbmMenuDot);
  713.     }
  714. #endif // _WIN32_WCE
  715. }
  716.  
  717. void CCmdUI::SetText(LPCTSTR lpszText)
  718. {
  719.     ASSERT(lpszText != NULL);
  720.     ASSERT(AfxIsValidString(lpszText));
  721.  
  722.     if (m_pMenu != NULL)
  723.     {
  724.         if (m_pSubMenu != NULL)
  725.             return; // don't change popup menus indirectly
  726.  
  727.         // get current menu state so it doesn't change
  728.         UINT nState = m_pMenu->GetMenuState(m_nIndex, MF_BYPOSITION);
  729.         nState &= ~(MF_BITMAP|MF_OWNERDRAW|MF_SEPARATOR);
  730.  
  731.         // set menu text
  732.         ASSERT(m_nIndex < m_nIndexMax);
  733.         VERIFY(m_pMenu->ModifyMenu(m_nIndex, MF_BYPOSITION |
  734.             MF_STRING | nState, m_nID, lpszText));
  735.     }
  736.     else
  737.     {
  738.         ASSERT(m_pOther != NULL);
  739.         AfxSetWindowText(m_pOther->m_hWnd, lpszText);
  740.     }
  741. }
  742.  
  743. BOOL CCmdUI::DoUpdate(CCmdTarget* pTarget, BOOL bDisableIfNoHndler)
  744. {
  745.     ASSERT_VALID(pTarget);
  746.  
  747.     if (m_nID == 0 || LOWORD(m_nID) == 0xFFFF)
  748.         return TRUE;     // ignore invalid IDs
  749.  
  750.     m_bEnableChanged = FALSE;
  751.     BOOL bResult = pTarget->OnCmdMsg(m_nID, CN_UPDATE_COMMAND_UI, this, NULL);
  752.     if (!bResult)
  753.         ASSERT(!m_bEnableChanged); // not routed
  754.  
  755.     if (bDisableIfNoHndler && !m_bEnableChanged)
  756.     {
  757.         AFX_CMDHANDLERINFO info;
  758.         info.pTarget = NULL;
  759.         BOOL bHandler = pTarget->OnCmdMsg(m_nID, CN_COMMAND, this, &info);
  760.  
  761. #ifdef _DEBUG
  762.         if ((afxTraceFlags & traceCmdRouting) && !bHandler)
  763.             TRACE1("No handler for command ID 0x%04X, disabling it.\n", m_nID);
  764. #endif
  765.         // Enable or Disable based on whether there is a handler there
  766.         Enable(bHandler);
  767.     }
  768.     return bResult;
  769. }
  770.  
  771. /////////////////////////////////////////////////////////////////////////////
  772. // Special init
  773.  
  774. #ifdef AFX_INIT_SEG
  775. #pragma code_seg(AFX_INIT_SEG)
  776. #endif
  777.  
  778. AFX_STATIC_DATA const BYTE _afxDot[] =
  779.     { 0x6, 0xF, 0xF, 0xF, 0x6 }; // simple byte bitmap, 1=> bit on
  780. #define DOT_WIDTH   4
  781. #define DOT_HEIGHT  5
  782.  
  783. #if !defined(_WIN32_WCE)
  784. AFX_STATIC void AFXAPI _AfxLoadDotBitmap()
  785. {
  786.     ASSERT(afxData.hbmMenuDot == NULL);
  787.     // attempt to load special bitmap, else default to arrow
  788.     CSize size = ::GetMenuCheckMarkDimensions();
  789.     ASSERT(size.cx > 4 && size.cy > 5); // not too small please
  790.     if (size.cx > 32)
  791.         size.cx = 32;
  792.     int iwRow = (size.cx + 15) >> 4;    // # of WORDs per raster line
  793.     int nShift = (size.cx - DOT_WIDTH) / 2;     // # of bits to shift over
  794.     nShift += ((iwRow * 16) - size.cx); // padding for word alignment
  795.     if (nShift > 16 - DOT_WIDTH)
  796.         nShift = 16 - DOT_WIDTH;    // maximum shift for 1 word
  797.  
  798.     if (size.cy > 32)
  799.         size.cy = 32;
  800.  
  801.     // bitmap 2/4/4/4/2 pixels wide - centered (0 => black)
  802.     BYTE rgbBitmap[32 * 2 * sizeof(WORD)];
  803.     memset(rgbBitmap, 0xff, sizeof(rgbBitmap));
  804.  
  805.     BYTE* pbOut = &rgbBitmap[iwRow * sizeof(WORD) *
  806.                             ((size.cy - (DOT_HEIGHT+1)) >> 1)];
  807.     const BYTE* pbIn = _afxDot;
  808.     for (int y = 0; y < DOT_HEIGHT; y++)
  809.     {
  810.         WORD w = (WORD)~(((DWORD)*pbIn++) << nShift);
  811.         // bitmaps are always hi-lo
  812.         pbOut[0] = HIBYTE(w);
  813.         pbOut[1] = LOBYTE(w);
  814.         pbOut += iwRow * sizeof(WORD);
  815.     }
  816.  
  817.     afxData.hbmMenuDot = ::CreateBitmap(size.cx, size.cy, 1, 1,
  818.             (LPVOID)&rgbBitmap);
  819.     if (afxData.hbmMenuDot == NULL)
  820.     {
  821.         TRACE0("Warning: using system arrow bitmap instead of dot.\n");
  822.         #define OBM_MNARROW         32739
  823.         afxData.hbmMenuDot = ::LoadBitmap(NULL, MAKEINTRESOURCE(OBM_MNARROW));
  824.     }
  825. }
  826. #endif // _WIN32_WCE
  827.  
  828. /////////////////////////////////////////////////////////////////////////////
  829. // CCmdTarget diagnostics
  830.  
  831. #ifdef _DEBUG
  832. void CCmdTarget::Dump(CDumpContext& dc) const
  833. {
  834.     CObject::Dump(dc);
  835.  
  836. #ifndef _AFX_NO_OLE_SUPPORT
  837.     if (m_xDispatch.m_vtbl != 0)
  838.     {
  839.         dc << "with IDispatch (OLE Automation) capability\n";
  840.         dc << "m_bResultExpected = " << m_bResultExpected << "\n";
  841.     }
  842.     if (m_xConnPtContainer.m_vtbl != 0)
  843.     {
  844.         dc << "with OLE Connection Point capability\n";
  845.     }
  846.     if (GetInterfaceMap() != &CCmdTarget::interfaceMap)
  847.     {
  848.         dc << "with OLE capability";
  849.         dc << "\nm_dwRef = " << m_dwRef;
  850.         dc << "\nm_pOuterUnknown = " << m_pOuterUnknown;
  851.         if (m_xInnerUnknown != 0)
  852.             dc << "\nwith aggregation capability";
  853.         dc << "\n";
  854.     }
  855. #endif //!_AFX_NO_OLE_SUPPORT
  856. }
  857.  
  858. void CCmdTarget::AssertValid() const
  859. {
  860.     CObject::AssertValid();
  861. }
  862. #endif
  863.  
  864. #ifdef AFX_INIT_SEG
  865. #pragma code_seg(AFX_INIT_SEG)
  866. #endif
  867.  
  868. IMPLEMENT_DYNAMIC(CCmdTarget, CObject)
  869.  
  870. /////////////////////////////////////////////////////////////////////////////
  871.